use clap::Parser;
use std::{fmt::{self}, str::FromStr};

use crate::cli::{verify_format, verify_input_filename};

#[derive(Debug, Clone, Copy)]  // 为什么可以copy?  它是在堆上的， 并没法有引用
pub enum OutputFormat {
    Json,
    Yaml,
    Toml,
}

#[derive(Debug, Parser)]
pub struct CsvOpts {
    #[arg(short, long, help = "input filename path", value_parser = verify_input_filename)]
    pub input: String,

    #[arg(short, long, help = "output filename path" )]
    pub output: Option<String>,

    #[arg(long, help = "output format , json , yaml , toml ", value_parser = verify_format, default_value = "json")]
    pub format: OutputFormat,

    #[arg(short, long, help = "delimiter", default_value_t = ',')]
    pub delimiter: char,

    // #[arg(short, long, help = "filter expression ")]
    // filter: Option<String>,

    #[arg( long, help = "CSV  has header or not , header", default_value_t = true)]
    pub header: bool,
}  



impl fmt::Display for OutputFormat {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // let s = match self {
        //     OutputFormat::Json => "json",
        //     OutputFormat::Yaml => "yaml",
        //     OutputFormat::Toml => "toml",
        //  //   OutputFormat::Xml => "xml",
        //   //  OutputFormat::Csv => "csv",
        // };
        // write!(f, "{}", s)

        write!(f,"{}",Into::<&'static str>::into(*self))
        // rust 中 From  和  Into  是一对互为反向的 trait
     // write(f,"{}", self.)
    }
    
}


impl FromStr for OutputFormat {
    //type Err = options::Err;
    type Err = anyhow::Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "json" => Ok(OutputFormat::Json),
            "yaml" => Ok(OutputFormat::Yaml),
            "toml" => Ok(OutputFormat::Toml),
         //   "xml" => Ok(OutputFormat::Xml),
          //  "csv" => Ok(OutputFormat::Csv),
            _ => Err(anyhow::anyhow!("Unsupported format")),
        }
    }
}

